﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace library
{
    partial class Peer //: IDisposable
    {
        DateTime lastGetPeerRequisition = DateTime.MinValue;

        bool endGetPeer;

        DateTime lastRequisition;

        internal Counter Distance = new Counter(10, 100);

        ManualResetEvent idlePeerEvent = new ManualResetEvent(false);

        ManualResetEvent idleGetPeerEvent = new ManualResetEvent(false);

        Action idlePeerAction;

        Action idleGetPeerAction;

        internal bool IsIdle
        {
            get
            {
                return DateTime.Now.Subtract(lastRequisition).TotalMilliseconds > Parameters.time_out;
            }
        }

        internal bool IsGetPeerIdle
        {
            get
            {
                return DateTime.Now.Subtract(lastGetPeerRequisition).TotalMilliseconds > Parameters.peers_interval;
            }
        }

        internal void CountRequisition()
        {
            lastRequisition = DateTime.Now;

            if (idlePeerAction == null)
            {
                idlePeerAction = () =>
                {
                    idlePeerEvent.WaitOne(Parameters.time_out);

                    Peers.idlePeerEvent.Set();
                };
            }

            idlePeerAction.BeginInvoke(null, null);
        }

        internal void BeginGetPeer()
        {
            if (!endGetPeer)
                EndGetPeer();

            lastGetPeerRequisition = DateTime.Now;

            endGetPeer = false;

            if (idleGetPeerAction == null)
            {
                idleGetPeerAction = () =>
                {
                    idleGetPeerEvent.WaitOne(Parameters.peers_interval);

                    Peers.idleGetPeerEvent.Set();
                };
            }

            idleGetPeerAction.BeginInvoke(null, null);
        }

        internal void EndGetPeer()
        {
            Distance.Add(Math.Min(Parameters.peers_interval, DateTime.Now.Subtract(lastGetPeerRequisition).TotalMilliseconds));

            endGetPeer = true;
        }

        internal bool HeIsDeadJim()
        {
            return Distance.Median.Equals(Parameters.time_out);
        }

        void busyTimerCallback(object o)
        {
            Peers.idlePeerEvent.Set();
        }

        void getPeerIntervalTimerCallback(object o)
        {
            Peers.idleGetPeerEvent.Set();
        }

        //void IDisposable.Dispose()
        //{
        //    //idleGetPeerEvent.Set();
        //}
    }
}

